/**************************************************************************************
 * Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
 * http://esper.codehaus.org *
 * http://www.espertech.com *
 * ---------------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the GPL license *
 * a copy of which has been included with this distribution in the license.txt file. *
 **************************************************************************************/
package com.espertech.esper.epl.agg.aggregator;

import java.util.HashMap;
import java.util.Map;

/**
 * Average that generates double-typed numbers.
 */
public class AggregatorAvg implements AggregationMethod, AggregationMethodSync
{

	public static final String SUM = "sum";
	public static final String NUMDATEPOINTS = "numDataPoints";

	private HashMap<String, Object> stateMap = new HashMap<String, Object>();

	protected double sum;
	protected long numDataPoints;

	@Override
	public void clear()
	{
		sum = 0;
		numDataPoints = 0;
	}

	@Override
	public void enter(Object object)
	{
		if (object == null)
		{
			return;
		}
		numDataPoints++;
		sum += ((Number) object).doubleValue();
	}

	@Override
	public void leave(Object object)
	{
		if (object == null)
		{
			return;
		}
		numDataPoints--;
		sum -= ((Number) object).doubleValue();
	}

	@Override
	public Object getValue()
	{
		if (numDataPoints == 0)
		{
			return null;
		}
		return sum / numDataPoints;
	}

	@Override
	public Class getValueType()
	{
		return Double.class;
	}

	@Override
	public void syncTo(Map<String, Object> stateMap) {
		// TODO Auto-generated method stub
		this.sum = (Double) stateMap.get(AggregatorAvg.SUM);
		this.numDataPoints = (Long) stateMap.get(AggregatorAvg.NUMDATEPOINTS);
	}

	@Override
	public Map<String, Object> syncFrom(int hashcode) {
		// TODO Auto-generated method stub
		stateMap.put(AggregatorAvg.SUM, this.sum);
		stateMap.put(AggregatorAvg.NUMDATEPOINTS, this.numDataPoints);
		return this.stateMap;
	}
}
